package com.example.component;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JWTUtils {

    // 用于加密的私钥
    private String secretKey="JWLDVPqenvlWn";

    // jwt有效期

    private Long expirePeriod=24L * 60 * 60 * 1000;

    /**
     * 创建 jwt
     */
    public String getJWT(String username) {
        // 计算过期时间
        Date now = new Date();
        Date expireTime = new Date(now.getTime() + expirePeriod);

        // 生成 JWT
        // JWT 携带的属性可以按需选择
        // 此处只设置了受众和过期时间
        return JWT
                .create()
                .withAudience(username)
                .withExpiresAt(expireTime)
                .sign(Algorithm.HMAC256(secretKey)); // 根据密钥设置签名, 算法也可以按需选择
    }

    /**
     * 解析 jwt
     */
    public Map<String, String> parseJWT(String jwt) {
        try {
            Map<String, String> map = new HashMap<>();
            DecodedJWT decodedjwt = JWT.require(Algorithm.HMAC256(secretKey))
                    .build().verify(jwt);
            // 创建时设置的属性都可以读取
            // 此处只读取了 Audience 作为演示
            String username = decodedjwt.getAudience().get(0);
            map.put("username", username);
            return map;
        }
        // 创建时如果设置了过期时间, 在解析时发现 jwt 过期即会抛出该异常
        catch (TokenExpiredException e) {
            throw new TokenExpiredException("jwt 已过期", Instant.now());
        }
        // JWTVerificationException 是验证时可能出现的各种异常的父类
        // 异常部分可以参考官方文档, 很多情况都有覆盖
        catch (JWTVerificationException e) {
            throw new JWTVerificationException("jwt 解析失败");
        }
    }
}

